// run: $exec < input > output
#include <iostream>
#include <queue>

int const maxn = 107;
char map[maxn][maxn];
bool type[maxn][maxn]; // true for corridors
bool vis[maxn][maxn];
int n, m;

int const opt[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};

bool judge_corridors(int x, int y)
{
	if (map[x][y] == '#') return false;
	int c1 = 0;
	for (int i = 0; i < 4; i += 2)
		if (map[x + opt[i][0]][y + opt[i][1]] == '#') c1++;
	int c2 = 0;
	for (int i = 1; i < 4; i += 2)
		if (map[x + opt[i][0]][y + opt[i][1]] == '#') c2++;
	return c1 >= 2 || c2 >= 2;
}

bool judge_inter(int x, int y)
{
	if (map[x][y] == '#') return false;
	int count = 0;
	for (int i = 0; i < 4; i++)
		if (map[x + opt[i][0]][y + opt[i][1]] == '#') count++;
	for (int i = 0; i < 4; i++)
		if (type[x + opt[i][0]][y + opt[i][1]]) count++;
	return count >= 3;
}

bool inrange(int x, int y)
{
	return ( 0 <= x && x <= n + 1) && (0 <= y && y <= m + 1);
}

bool next_to_out_cart(int x, int y)
{
	for (int i = 0; i < 4; i++) {
		int tx = x + opt[i][0];
		int ty = y + opt[i][1];
		if (!((0 < tx && tx <= n) && (0 < ty && ty < m))) continue;
		if (vis[tx][ty]) return true;
	}
	return false;
}

bool movable(int x, int y, int d)
{
	int tx = x + opt[d][0];
	int ty = y + opt[d][1];
	if (!((0 < tx && tx <= n) && (0 < ty && ty <= m))) return false;
	if (map[tx][ty] != '.') return false;
	return true;
}

bool dfs(int x, int y, int d)
{
	std::cout << x << ' ' << y << ' ' << d << '\n';
	if (vis[x][y]) return false;
	if (!type[x][y] && !vis[x][y]) return true;
	bool turned = false;
	for (int ti = 0; ti < 5 && !movable(x, y, d); d = (d + 1) % 4, ti++) turned = true;
	if (!movable(x, y, d)) return false;
	if (!turned && movable(x, y, (d + 1) % 4)) d++;
	return dfs(x + opt[d][0], y + opt[d][1], d);
}

int main()
{
	std::cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) std::cin >> map[i][j];
	for (int i = 0; i <= n; i++) map[i][0] = map[i][m + 1] = '.';
	for (int i = 0; i <= m; i++) map[0][i] = map[n + 1][i] = '.';

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			type[i][j] = judge_corridors(i, j);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			type[i][j] = judge_inter(i, j);

	typedef std::pair<int, int> pair_type;
	std::queue<pair_type> q;
	q.push(std::make_pair(0, 0));
	vis[0][0] = true;
	while (!q.empty()) {
		pair_type now = q.front(); q.pop();

		for (int i = 0; i < 4; i++) {
			int tx = now.first + opt[i][0];
			int ty = now.second + opt[i][1];
			if (!inrange(tx, ty)) continue;
			if (map[tx][ty] == '.' && !type[tx][ty] && !vis[tx][ty]) {
				q.push(std::make_pair(tx, ty));
				vis[tx][ty] = true;
			}
		}
	}
	pair_type in;
	int dir = -1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (type[i][j] && next_to_out_cart(i, j)) {
				in.first = i;
				in.second = j;
				for (dir = 0; dir < 4; dir++) {
					int tx = i + opt[dir][0];
					int ty = j + opt[dir][1];
					if (map[tx][ty] == '.' && !vis[tx][ty]) break;
				}
				break;
			}
		}
		if (dir != -1) break;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) std::cout << type[i][j];
		std::cout << '\n';
	}
	if (dfs(in.first, in.second, dir))
		std::cout << "YES\n";
	else
		std::cout << "NO\n";
}

